#include "utils.h"
#include <time.h>
#include <string.h>

float rand_uniform(float min, float max) {
    if (max < min) {
        float swap = min;
        min = max;
        max = swap;
    }
    return ((float)rand() / RAND_MAX * (max - min)) + min;
}

float sum_array(float *a, int n) {
    int i;
    float sum = 0;
    for (i = 0; i < n; ++i) sum += a[i];
    return sum;
}

// From http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
float rand_normal()
{
    static int haveSpare = 0;
    static double rand1, rand2;

    if(haveSpare)
    {
        haveSpare = 0;
        return sqrt(rand1) * sin(rand2);
    }

    haveSpare = 1;

    rand1 = rand() / ((double) RAND_MAX);
    if(rand1 < 1e-100) rand1 = 1e-100;
    rand1 = -2 * log(rand1);
    rand2 = (rand() / ((double) RAND_MAX)) * TWO_PI;

    return sqrt(rand1) * cos(rand2);
}

void swap(void *a, void *b, size_t size) {
    char temp[size];
    memcpy(temp, a, size);
    memcpy(a, b, size);
    memcpy(b, temp, size);
}

// 通用Fisher-Yates洗牌算法
void shuffle(void* array, size_t count, size_t size) {
    srand(time(NULL));
    char *base = (char*)array;
    for (size_t i = count - 1; i > 0; i--) {
        size_t j = rand() % (i + 1);
        swap(base + i * size, base + j * size, size);
    }
}

// 根据索引数组重新排列数据
void reorder_array(void *array, int *indices, int size, size_t element_size) {
    void *temp = malloc(element_size * size);
    if (temp == NULL) {
        fprintf(stderr, "Memory allocation failed!\n");
        return;
    }

    // 根据索引数据重新排列数据
    for (int i = 0; i < size; i++) {
        memcpy(temp + i * element_size, (array + indices[i] * element_size), element_size);
    }

    // 将重新排列的数据复制回原数组
    memcpy(array, temp, size * element_size);
    free(temp);
}

float* pad(image *img, int srcSize, int targetSize) {
    int sSize = srcSize * srcSize;
    int tSize = targetSize * targetSize;
    int mid = ceil((targetSize - srcSize) / 2);
    int half = ceil(srcSize / 2);
    int xStart = mid - half;
    int xEnd = mid + half;
    int yStart = mid - half;
    int yEnd = mid + half;
    float *temp = calloc(1, sizeof(float) * tSize);
    // for (int i = 0; i < targetSize; i++) {
    //     for (int j = 0; j < targetSize; j++) {
    //         // if (i >= xStart && i < xEnd && j >= yStart && j < yEnd
    //         // ) {
    //         //     int srcJ = 
    //         //     temp[i * targetSize + j] = img->data[i * srcSize + j];
    //         // } else {
    //             temp[i * targetSize + j] = 0.5;
    //         // }
    //     }
    // }
    return temp;
}

char *copy_string(char *s) {
    char *copy = malloc(strlen(s) + 1);
    strncpy(copy, s, strlen(s) + 1);
    return copy;
}

char* basecfg(char *cfgfile) {
    char *c = cfgfile;
    char *next;
    while ((next = strchr(c, "/"))) {
        c = next + 1;
    }
    c = copy_string(c);
    next = strchar(c, ".");
    if (next) *next = 0;
    return c;
}